/***************************************************************************
 *   Copyright (C) 2008 by Branan Riley   *
 *   branan@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "renderview.h"

#include <QMouseEvent>

#include "lwoloader.h"
#include "aseloader.h"

RenderView::RenderView(QWidget *parent)
 : QGLWidget(parent)
{
  setupWidget();
}

RenderView::RenderView(QGLContext *context, QWidget *parent)
  : QGLWidget(context, parent)
{
  setupWidget();
}

RenderView::RenderView(const QGLFormat &format, QWidget *parent)
  : QGLWidget(format, parent)
{
  setupWidget();
}

RenderView::~RenderView()
{
}

void RenderView::setModel(const QString &file)
{
  // reset rotation for the new model
  _rot_x = 0.0f;
  _rot_y = 0.0f;
  _zoom = -100.0f;

  ModelLoader *loader = 0;

  if(file.endsWith("lwo", Qt::CaseInsensitive)) {
    loader = _lwo_loader;
    qDebug("Using LWO loader...");
  } else if(file.endsWith("ase", Qt::CaseInsensitive)) {
    loader = _ase_loader;
    qDebug("Using LWO loader...");
  } else {
    qDebug("Somehow, we got a file that isn't LOW or ASE...");
  }

  if(loader && loader->loadFile(file)) {
    delete[] _vertices;
    _vertices = loader->vertices();

    delete[] _normals;
    _normals = loader->normals();

//    delete[] _texcoords;
//    _texcoords = loader->texcoords();

    delete[] _indices;
    _indices = loader->indices();

    _index_count = loader->numIndices();

    setupGlPointers();
    updateGL();
  }
}

void RenderView::initializeGL()
{
  qglClearColor(Qt::black);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
  glEnableClientState(GL_VERTEX_ARRAY);
//  glEnableClientState(GL_COLOR_ARRAY);
  glEnableClientState(GL_NORMAL_ARRAY);
//  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  // Lighting Stuff
  glEnable(GL_LIGHTING);
  glEnable(GL_COLOR_MATERIAL);
  glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  GLfloat DiffuseLight[] = {0.8f, 0.8f, 0.8f, 1.0f};
  GLfloat AmbientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
  GLfloat LightPos[] = {-50.0f, 50.0f, 100.0f, 1.0f};
  glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);
  glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
  glEnable(GL_LIGHT0);
  glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
  
}

void RenderView::resizeGL(int width, int height)
{
  glViewport(0, 0, width, height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  GLfloat x = GLfloat(width) / GLfloat(height);
  gluPerspective(60.0f, x, 1.0f, 1000.0f);
  glMatrixMode(GL_MODELVIEW);
}

void RenderView::paintGL()
{
  if(_indices) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, _zoom);
    glRotatef(_rot_x, 1.0f, 0.0f, 0.0f);
    glRotatef(_rot_y, 0.0f, 1.0f, 0.0f);
    glDrawElements(GL_TRIANGLES, _index_count, GL_UNSIGNED_INT, _indices);
  }
}

void RenderView::mousePressEvent(QMouseEvent *event)
{
  _last_pos = event->pos();
}

void RenderView::mouseMoveEvent(QMouseEvent *event)
{
  float dx = float(event->x() - _last_pos.x()) / width();
  float dy = float(event->y() - _last_pos.y()) / height();

  if(event->buttons() & Qt::LeftButton) {
    _rot_x += 180 * dy;
    _rot_y += 180 * dx;
    updateGL();
  } else if(event->buttons() & Qt::RightButton) {
    _zoom += 50*dy;
    updateGL();
  }
  _last_pos = event->pos();
}

void RenderView::setupGlPointers()
{
  glVertexPointer(3, GL_FLOAT, 0, _vertices);
  glNormalPointer(GL_FLOAT, 0, _normals);
}

void RenderView::setupWidget()
{
  QSizePolicy policy;
  setMinimumSize(250,250);

  policy.setHorizontalStretch(2);
  policy.setHorizontalPolicy(QSizePolicy::Expanding);
  policy.setVerticalPolicy(QSizePolicy::Expanding);

  setSizePolicy(policy);

  _lwo_loader = new LwoLoader(this);
  _ase_loader = new AseLoader(this);

  _indices = 0;
  _vertices = 0;
  _normals = 0;
  _texcoords = 0;
}
